Responsibility-driven design

Responsibility-driven design is a design technique in Object-oriented programming. It was proposed by Rebecca Wirfs-Brock and Brian Wilkerson who defined it as follows:

Responsibility-driven design is inspired by the client/server model. It focuses on the contract by asking:

  • What actions is this object responsible for?
  • What information does this object share?

Responsibility-driven design is in direct contrast with Data-driven design, which promotes defining the behavior of a class along the data that it holds. Data-driven design is not the same as Data-driven programming which is concerned with using data to determine control flow not class design.

The client/server model they refer to assumes that a software client and a software server exchange information based on a contract that both parties commit to adhere to. The client may only make the requests specified, the server must answer them. Thus, responsibility-driven design tries to avoid dealing with details, such as the way in which requests are carried out, by instead only specifying the intent of a certain request. The benefit is increased encapsulation, since the specification of the exact way in which a request is carried out is private to the server.

To further the encapsulation of the server, Wirfs-Brock and Wilkerson call for language-features that limit outside influence to the behavior of a class. They demand that visibility of members and function should be finely grained, such as in Eiffel. Even finer control of the visibility of even classes is available in the Newspeak programming language.

Contents

Building Blocks of RDD

In their book Object Design: Roles, Responsibilities and Collaborations[1] the authors describe the following building blocks that make up Responsibility-Driven Design.

Application

A software application is referred to as a set of interacting objects[2]

Candidates

Candidates or candidate objects are key concepts in the form of objects described on CRC cards. They serve as initial inventions in the process of object design.[3]

Collaborations

A collaboration is defined as an interaction of objects or roles (or both)[2].

CRC Cards

CRC stands for Candidates, Responsibilities, Collaborators. They are index cards used in early design for recording candidates[4]. These cards are split up into an unlined and a lined side.

Content of lined side

On this side the candidate's name, its responsibilities and its collaborators are recorded[4].

Content of unlined side

On this side the candidate's name, its purpose in the application, stereotype roles and anything worthwile such as the names of roles in patterns it participates in are recorded[4].

Hot Spots

Hot Spots are points in the application where variations occur. They are recorded using Hot Spot Cards[5].

Hot Spot Cards

Hot Spot Cards are used for recording variations, so called hot spots. They are similarly to CRC cards low-level tools in the form of index cards[5]. These cards consist of:

Objects

Objects are described as things that have machinelike behaviors that can be plugged together to work in concert. These objects play well-defined roles and encapsulate scripted responses and information[2].

Object Neighborhoods

Another term for subsystem[6]. It is a logical grouping of collaborators[6].

Responsibilities

A responsibility is an obligation to perform a task or know information[2]. These are further categorized according to their usage scenario.

Public Responsibilities

Public responsibilities are the responsibilities an object offers as services to others and the information it provides to others[7].

Private Responsibilities

Private responsibilities are the actions an object takes in support of public responsibilities[7]

Subresponsibilities

These responsibilities come into existence whenever a large or complicated responsibility is split up into smaller ones[8]. They are further categorized by what they do.

Subordinate Responsibilities

These are the major steps of the subresponsibility[8].

Sequencing Responsibility

This responsibility refers to the sequencing of the execution of subordinate responsibilities[8].

Roles

A role is a set of related responsibilities[2]. They can be implemented as classes and interfaces. Interfaces, however, are the preferred implementation as they increase flexibility by hiding the concrete class which ultimately does the work[9].

Role Stereotypes

Role stereotypes are simplified roles that come with predefined responsibilities[10]. There are several categories.

Controller

Objects implementing this role make decisions and closely direct the action of other objects[10].

Coordinator

This role reacts to events by delegating tasks to others[10].

Information Holder

Information holder know and provide information [10].

Information Provider

A slight variation of an information holder is the information provider, which takes a more active role in managing and maintaining information. This distinction can be used if a designer needs to get more specific[11].

Interfacer

This role transforms information and requests between distinct parts of an application[10]. It is further divided into more specific roles.

External Interfacer

These interfacers communicate with other applications than your own.[11]. They are mainly used for encapsulating non-object-oriented APIs and do not collaborate a lot.[12].

Internal Interfacer

Also called intersystem interfacers[11]. These interfacers act as a bridge between object neighborhoods[12].

User Interfacer

These interfacers communicate with users by responding to events generated in the UI and then passing them on to more appropriate objects. [11][13][12]

Service Provider

This role performs work and offers computing services[11].

Structurer

This role maintains relationships between objects and information about those relationships[11].

Control Style

An important part in the Responsibility-Driven Design process is the distribution of control responsibilities that results in developing a control style.

Concept of Control

Control styles relie heavily on the concept of Control. Therefore it makes sense to properly define the term. It is defined as decision making and selection of paths through an application[14].

Control Centers

An important aspect of developing a control style is the invention of so called control centers. These are places where objects charged with controlling and coordinating reside.[15].

Control Style Variations

A control style comes in three distinct variations. These are not precise definitions though since a control style can be said to be more centralized or delegated than another.

Centralized Control Style

This control style inflicts a procedural paradigma on the structure of the application and places major-decision making responsibilities in only a few objects.

Advantages
Disadvantages
When to use

When decisions to be made are few, simple, and related to a single task.

Clustered Control Style

This control style is a variation of the centralized control style wherein control is factored among a group of objects whose actions are coordinated[16]. The main difference between a clustered and delegated control style is that in a clustered control style, the decision making objects are located within a control center whereas in a delegated control style they are mostly outside[17].

Advantages
Disadvantages
When to use

When decisions to be made are few, simple, and related to a single task.

Delegated Control Style

A delegated control style lies in between a centralized and dispersed control style. It passes some of the decision making and much of the action to objects surrounding a control center. Each neighboring object has a signifcant role to play.

Advantages
Disadvantages
When to use

When you want to delegate work to objects that are more specialized.

Dispersed Control Style

A dispersed control style does not contain any control centers. The logic is spread across the entire population of objects, keeping each object small and building in as few dependencies among them as possible[19].

Advantages
Disadvantages
When to use

Never.

Preferred Control Style

The inventors of Responsibility-Driven Design recommend using a delegated control style because no one object knows or does too much[20].

Conflict with the law of Demeter

According to Wirfs-Brock and Wilkerson, there's a conflict between the Law of Demeter and Responsibility-driven design. The law of Demeter says that messages can be sent only to the following: message argument, instance variable, new objects, global variables. Therefore, sending a message to the result of a previous message send isn't allowed. However, "returned values are part of the client/server contract. There need be no correlation between the structure of an object and the object returned by the message."

References

Bibliography